
#pragma once

#include <ReloadUdpCallPacket/stdafx.h>
#include <ReloadUdpCallPacket/ConstDef.h>
#include <ReloadUdpCallPacket/Logger.h>
#include <ReloadUdpCallPacket/ReloadCode.h>
#include <ReloadUdpCallPacket/Interface.h>
#include <ReloadUdpCallPacket/IoBuffer.h>
#include <ReloadUdpCallPacket/Packet.h>
#include <ReloadUdpCallPacket/ReloadPacket.h>
#include <ReloadUdpCallPacket/ReloadConfigure.h>

enum ReloadUdpCall_ListeningPort
{
	ReloadUdpCall_ListeningPort_Store = 8400,
	ReloadUdpCall_ListeningPort_Fetch = 8401,
	ReloadUdpCall_ListeningPort_AppAttach = 8402
};

namespace ReloadUdpCall
{
	const std::size_t maxReloadUdpCallPacketSize = 1000;

	#define RELOAD_TOKEN	0xd2454c4f

	class SerializeString : public NumericVarArray<byte, byte>
	{
	public:
		SerializeString();
		SerializeString(const std::vector<byte>& _array);
		SerializeString(const char* _cstr);
		SerializeString(const std::string& _str);
		virtual ~SerializeString();

		retT setValue(const std::vector<byte>& _array);
		retT setValue(const char* _cstr);
		retT setValue(const std::string& _str);

		std::string toString();
	};

	class ReloadUdpCallPacketBase : public PacketElement
	{
	public:
		ReloadUdpCallPacketBase();
		virtual ~ReloadUdpCallPacketBase();

		virtual retT readFromBufferNoCheck( boost::shared_ptr<IoBuffer> _pBuffer);
		virtual retT writeToBufferNoCheck( boost::shared_ptr<IoBuffer> _pBuffer);

		virtual retT readFromBuffer( boost::shared_ptr<IoBuffer> _pBuffer);
		virtual retT writeToBuffer( boost::shared_ptr<IoBuffer> _pBuffer);

		virtual std::size_t size();
		virtual retT attachRootElement(boost::weak_ptr<PacketElement> _pRootElement);

		SerializeString	overlayInstanceName_;
		SerializeString	resourceName_;
	};

	class SendStoreReqUdpCallPacket : public ReloadUdpCallPacketBase
	{
	public:
		SendStoreReqUdpCallPacket();
		virtual ~SendStoreReqUdpCallPacket();

		virtual retT readFromBuffer( boost::shared_ptr<IoBuffer> _pBuffer);
		virtual retT writeToBuffer( boost::shared_ptr<IoBuffer> _pBuffer);

		virtual std::size_t size();

		StructVarArray<uint32, StoreKindData> kindData_;
	};

	class SendFetchReqUdpCallPacket : public ReloadUdpCallPacketBase
	{
	public:
		SendFetchReqUdpCallPacket();
		virtual ~SendFetchReqUdpCallPacket();

		virtual retT readFromBuffer( boost::shared_ptr<IoBuffer> _pBuffer);
		virtual retT writeToBuffer( boost::shared_ptr<IoBuffer> _pBuffer);

		virtual std::size_t size();
		virtual retT attachRootElement(boost::weak_ptr<PacketElement> _pRootElement);

		StructVarArray<uint16, StoredDataSpecifier> specifiers_;
	};

	class ReloadUdpCallResultBase : public PacketElement
	{
	public:
		ReloadUdpCallResultBase();
		virtual ~ReloadUdpCallResultBase();

		virtual retT readFromBufferNoCheck( boost::shared_ptr<IoBuffer> _pBuffer);
		virtual retT writeToBufferNoCheck( boost::shared_ptr<IoBuffer> _pBuffer);

		virtual retT readFromBuffer( boost::shared_ptr<IoBuffer> _pBuffer);
		virtual retT writeToBuffer( boost::shared_ptr<IoBuffer> _pBuffer);

		virtual std::size_t size();

		int result_;
	};

	class SendFetchReqUdpCallResult : public ReloadUdpCallResultBase
	{
	public:
		SendFetchReqUdpCallResult();
		virtual ~SendFetchReqUdpCallResult();

		virtual retT readFromBuffer( boost::shared_ptr<IoBuffer> _pBuffer);
		virtual retT writeToBuffer( boost::shared_ptr<IoBuffer> _pBuffer);

		virtual std::size_t size();
		virtual retT attachRootElement(boost::weak_ptr<PacketElement> _pRootElement);

		StructVarArray<uint32, FetchKindResponse> kindResponses_;
	};

	class SendAppAttachReqUdpCallResult : public ReloadUdpCallResultBase
	{
	public:
		SendAppAttachReqUdpCallResult();
		virtual ~SendAppAttachReqUdpCallResult();

		virtual retT readFromBuffer( boost::shared_ptr<IoBuffer> _pBuffer);
		virtual retT writeToBuffer( boost::shared_ptr<IoBuffer> _pBuffer);

		virtual std::size_t size();
		virtual retT attachRootElement(boost::weak_ptr<PacketElement> _pRootElement);

		SerializeString strIP_;
	};
}
